#include "parse_Rxpacket.h"

u32 busService = 0;
u32 *Fifo_InstancePtr = NULL;
struct Eth_status_cnt Eth_status = {0};


int parse_Rxpacket(const EthernetFrame *FramePtr)
{
    u32 sum = 0;
    char *rcvFramePtr = (char *)FramePtr;
    struct eth_header *ethhdr = (struct eth_header *)rcvFramePtr;

    if (ethhdr->ether_type != 0xDD86) // 判断IPV6包 注意大小端
    {
        return -1; // 不是IPv6数据包
    }

    struct ipv6_header *ip6hdr = (struct ipv6_header *)(rcvFramePtr + IPV6_HEADER_LOC);
    if (ip6hdr->next_header == ICMPV6_PROTOCOL) // ICMPv6 进行应答
    {
        struct icmpv6_msg *icmp6_rx = (struct icmpv6_msg *)(rcvFramePtr + ICMP_HEADER_LOC);

        EthernetFrame ICMPv6Frame; /* 构建icmp包 并初始化*/
        eth_ICMPv6Frame_init(&ICMPv6Frame);

        // 将收到的源MAC地址改为发送的目的地址
        struct eth_header *tx_eth_hdr = (struct eth_header *)(ICMPv6Frame);
        memcpy(tx_eth_hdr->dst_mac, ethhdr->src_mac, XAE_MAC_ADDR_SIZE);

        // 将收到的源IP地址改为发送IP地址
        struct ipv6_header *txiphdr = (struct ipv6_header *)(ICMPv6Frame + IPV6_HEADER_LOC);
        struct ipv6_header *rxiphdr = (struct ipv6_header *)(rcvFramePtr + IPV6_HEADER_LOC);
        memcpy(txiphdr->dst_ipaddr, rxiphdr->src_ipaddr, 16);

        struct icmpv6_msg *icmp_tx = (struct icmpv6_msg *)(ICMPv6Frame + ICMP_HEADER_LOC);
        icmp_tx->identifier = icmp6_rx->identifier;
        icmp_tx->sequence = icmp6_rx->sequence;
        icmp_tx->type = 129; // ICMPv6回显应答类型
        icmp_tx->code = 0;   // 代码为0
        memcpy(icmp_tx->icmpv6_data, icmp6_rx->icmpv6_data, sizeof(icmp6_rx->icmpv6_data));
        sum = transLayer_checksum(&ICMPv6Frame);
        icmp_tx->checksum = Xil_Htons(sum);

        eth_FifoTransData(Fifo_InstancePtr, &ICMPv6Frame, (u32)(sizeof(struct eth_icmpv6_frame)));
        B1553_TMadd_Comm_Eth_TX_Count(&busService); // 遥测+1

        return 0;
    }

    if (ip6hdr->next_header == UDP_PROTOCOL) // UDP数据包 在轨更新包
    {
        struct udp_header *udphdr = (struct udp_header *)(rcvFramePtr + UDP_HEADER_LOC);

        udphdr->dst_port = Xil_Htons(udphdr->dst_port);
        if (udphdr->dst_port < 50000)
        {
            return -1; // 端口号错误 返回
        }

        struct app_header *apphdr = (struct app_header *)(rcvFramePtr + APP_HEADER_LOC);
        if ((0x01 != apphdr->data_type) || (0x29 != apphdr->port)) // 判断类型和端口
        {
            B1553_TMadd_Comm_Update_Error_Count(&busService);
            B1553_TMset_Update_stat(&busService, PROGRAM_UPDATE_AOS_ERR);
            return -1;
        }

        struct app_vcdu_prog *vcduprog = (struct app_vcdu_prog *)(rcvFramePtr + APP_VCDU_DATA_LOC);

        //        u16 foo_crc = vcdu_crc16_checksum(FramePtr);

        // if (foo_crc != vcduprog->crc) // CRC校验错误 遥测错误计数+1
        // {
        //     B1553_TMadd_Comm_Update_Error_Count();
        //     B1553_TMset_Update_stat(PROGRAM_UPDATE_CRC_ERR);
        //     return -1;
        // }
        // else
        // {
        // }

        // if (vcduprog->bitstream_cnt != Eth_status.update_expect_cnt) // 位流计数与预期计数不符
        // {
        //     B1553_TMadd_Comm_Update_Error_Count();
        //     B1553_TMset_Update_stat(PROGRAM_UPDATE_WRONG_CNT);
        //     return -1;
        // }
        // else
        // {
        // }

        // 发送数据
        // dbg_print(vcduprog->bit_stream_data, 539);
        uart_rs01_send(vcduprog->bit_stream_data, 539);

        // 预期接收计数+1
        ++Eth_status.update_expect_cnt;

        B1553_TMadd_Comm_Update_Count(&busService); // 接收计数+1

        if (Eth_status.update_expect_cnt < 256) // 一个扇区128K字节 256包数据每包512字节
        {
            B1553_TMset_Update_stat(&busService, PROGRAM_UPDATING); // 设置正在更新的标志
            Eth_status.update_status = PROGRAM_UPDATING;
        }
        else // 等于255 或者大于 255 更新完成
        {
            B1553_TMset_Update_stat(&busService, PROGRAM_UPDATE_DONE); // 测试用 更新完成

            Eth_status.update_status = PROGRAM_UPDATE_DONE;

            uart_rs01_sendTM(); //  发送遥测
            uart_rs01_rcvTM();
        }

        return 0;
    }

    return -1;
}